package cn.demo.security;

import cn.demo.entity.Permission;
import cn.demo.entity.Role;
import cn.demo.entity.UserInfo;
import cn.demo.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import java.util.ArrayList;
import java.util.List;

public class SecurityUserDetailsService implements UserDetailsService {

    //依赖注入UserInfoService
    @Autowired
    private UserInfoService userInfoService;
    //依赖注入BCrypt加密算法对象
    @Autowired
    private BCryptPasswordEncoder passwordByAuth;


    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //1. 根据用户标识（用户名），从数据库读取用户信息
        UserInfo user = userInfoService.findByUsername(username);
        if (user == null) {
            return null;
        }
        //2. 提取用户信息的角色与权限关键词信息
        //3. 把用户角色与权限关键词封装为List<GrantedAuthority>列表
        List<GrantedAuthority> authorityList = new ArrayList<>();
        //获取当前User中的角色
        Role role = user.getRole();
        //把每一个角色的关键字 存入到集合中
        authorityList.add(new SimpleGrantedAuthority(role.getKeyword()));
        //获取当前的角色Role下的 所有权限
        for (Permission permission : role.getPermissions()) {
            //把每一个权限的关键字，存入到集合中
            authorityList.add(new SimpleGrantedAuthority(permission.getKeyword()));
        }


        //如果密码未加密, 必须用默认加密规则加密
        //如果密码已加密,则不用使用默认规则加密
      /*  String passwordByDB = user.getUserPassword();
        String passwordByAuth = "{noop}" + passwordByDB;*/

        //使用BCrypt加密算法
        //String passwordByAuth = this.passwordByAuth.encode(passwordByDB);

        //4. 构建UserDetails对象（使用Security框架自动的User类封装），封装用户名、密码（必须是加密过的）及权限角色关键词列表
        UserDetails userDetails =
                new org.springframework.security.core.userdetails.User(user.getUserCode(), user.getUserPassword(), authorityList);

        //打印对象信息
        System.out.println("userDetails====================" + userDetails);
       // System.out.println("passwordByAuth===================" + passwordByAuth);

        return userDetails;
    }
}















